package ru.autofan.logic;

import java.util.HashMap;
import java.util.Map;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import ru.autofan.aop.RequestInterceptor;
import ru.autofan.domain.AuthRole;
import ru.autofan.domain.User;
import ru.autofan.secure.AuthRoleSupport;
import ru.autofan.secure.CurrentRolesHolder;
import ru.autofan.secure.Restricted;

public class LoginService extends BasicService {

	public static final String LOGGED_USER_ATTR = "user_attr";

	private CurrentRolesHolder currentRolesHolder;

	public CurrentRolesHolder getCurrentRolesHolder() {
		return currentRolesHolder;
	}

	public void setCurrentRolesHolder(CurrentRolesHolder currentRolesHolder) {
		this.currentRolesHolder = currentRolesHolder;
	}

	public boolean isLogged() {
		return RequestInterceptor.httpSessionHolder.get().getAttribute(
				LOGGED_USER_ATTR) == null ? false : true;
	}

	public Long getUserId() {
		return (Long) RequestInterceptor.httpSessionHolder.get().getAttribute(
				LOGGED_USER_ATTR);
	}

	@Restricted(authRoleSupport = AuthRoleSupport.USER)
	public void logout() {
		if (isLogged()) {
			RequestInterceptor.httpSessionHolder.get().setAttribute(
					LOGGED_USER_ATTR, null);
		}
	}

	public boolean login(String email, String pwd) {
		if (isLogged()) {
			return false;
		}
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("email", email);
		params.put("uPassword", pwd);

		User user = null;
		try {
			final String query = "from User where email=:email and uPassword=:uPassword";
			user = (User) getDaoSupporter().getUniqueObject(User.class, query,
					params);
		} catch (Exception e) {
		} finally {
			if (user == null) {
				return false;
			}
		}
		RequestInterceptor.httpSessionHolder.get().setAttribute(
				LOGGED_USER_ATTR, user.getId());
		getCurrentRolesHolder().setRoles(user.cloneRoles());
		return true;
	}

	/** Validate local thread roles with logged user roles */
	public void validate() {
		if (!isLogged()) {
			AuthRole basicRole = new AuthRole("ANONYMOUS");
			getCurrentRolesHolder().setRole(basicRole);
			return;
		} else {
			User user = getDomainFactory().get(User.class, getUserId());
			if (user != null && !user.getRoles().equals(
							getCurrentRolesHolder().getRoles())) {
				getCurrentRolesHolder().setRoles(user.getRoles());
			}
		}
	}

	@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
	public String getLoggedUserName() {
		User user = getDomainFactory().get(User.class, getUserId());
		return user != null ? user.getName() : null;
	}

	@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
	public User getLoggedUser() {
		return getDomainFactory().get(User.class, getUserId());
	}
}
